home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / m2posx10.zoo / m2posix.10 / src / proc.dpp < prev    next >
Encoding:
Modula Definition  |  1993-12-21  |  28.0 KB  |  511 lines

  1. DEFINITION MODULE proc;
  2. __DEF_SWITCHES__
  3. #ifdef HM2
  4. #ifdef __LONG_WHOLE__
  5. (*$!i+: Modul muss mit $i- uebersetzt werden! *)
  6. (*$!w+: Modul muss mit $w- uebersetzt werden! *)
  7. #else
  8. (*$!i-: Modul muss mit $i+ uebersetzt werden! *)
  9. (*$!w-: Modul muss mit $w+ uebersetzt werden! *)
  10. #endif
  11. #endif
  12. (*****************************************************************************)
  13. (* Funktionen, die mit Prozessen zu tun haben.                               *)
  14. (*                                                                           *)
  15. (* Ein Fehler ist immer dann aufgetreten, wenn bei Funktionen mit Typ INTEGER*)
  16. (* ein negativer Wert zurueckgegeben wird.                                   *)
  17. (* Die genaue Fehlerursache kann bei Bedarf ueber "err.errno" und die ent-   *)
  18. (* sprechenden Konstanten ermittelt werden. Die Funktionen veraendern "errno"*)
  19. (* nur dann, wenn ein Fehler aufgetreten ist, bei erfolgreicher Ausfuehrung  *)
  20. (* wird "errno" nicht veraendert.                                            *)
  21. (*                                                                           *)
  22. (* GEMDOS:                                                                   *)
  23. (* Die Eigenschaften der Funktionen unter dem ``blanken'' GEMDOS sind z.T.   *)
  24. (* stark eingeschraenkt; unter dem Stichwort GEMDOS ist deswegen immer       *)
  25. (* angegeben, in wieweit die Funktion emuliert werden kann. Ist MiNT-Unter-  *)
  26. (* stuetzung angegeben, so ist unter der Betriebssystemerweiterung MiNT      *)
  27. (* eine bessere Unterstuetzung der Funktionen zu erwarten; wie weit diese    *)
  28. (* geht, ist unter dem Stichwort MiNT angegeben.                             *)
  29. (* --------------------------------------------------------------------------*)
  30. (* 16-Dez-93, Holger Kleinschmidt                                            *)
  31. (*****************************************************************************)
  32.  
  33. FROM PORTAB IMPORT
  34. (* TYPE *) ANYLONG, WORDSET;
  35.  
  36. FROM types IMPORT
  37. (* TYPE *) uidT, gidT, pidT, clockT, StrArray;
  38.  
  39. (*=========================== "times()" =====================================*)
  40.  
  41. TYPE
  42.   TmsRec = RECORD
  43.     tmsUtime  : clockT; (* CPU-Zeit im Benutzercode *)
  44.     tmsStime  : clockT; (* CPU-Zeit im System *)
  45.     tmsCUtime : clockT; (* CPU-Zeit im Benutzercode aller beendeten Unterpr.*)
  46.     tmsCStime : clockT; (* CPU-Zeit im System aller beendeten Unterprozesse *)
  47.   END;
  48.  
  49. (*=========================== "tfork()" =====================================*)
  50. (* nicht POSIX: *)
  51. CONST
  52.   MINSTACKSIZE = 4096;
  53.  
  54. TYPE
  55.   ThreadProc = PROCEDURE(ANYLONG): INTEGER;
  56.  
  57. (*======================= "wait()", "waitpid()" =============================*)
  58.  
  59. TYPE
  60.   WaitVal = WORDSET;
  61.  
  62. (* Repraesentation des Typs 'WaitVal' ist nicht zur Benutzung
  63.  * ausserhalb des Moduls gedacht.
  64.  * Konstanten sind nicht POSIX.
  65.  *)
  66. CONST
  67. #if reverse_set
  68.   wRetcode  = WaitVal{0..7};
  69.   wTermsig  = WaitVal{9..15};
  70.   wCoredump = 8;
  71.   wStopval  = WaitVal{8..15};
  72.   wStopsig  = WaitVal{0..7};
  73.  
  74.   WSTOPPED  = WaitVal{9..15};
  75. #else
  76.   wRetcode  = WaitVal{8..15};
  77.   wTermsig  = WaitVal{0..6};
  78.   wCoredump = 7;
  79.   wStopval  = WaitVal{0..7};
  80.   wStopsig  = WaitVal{8..15};
  81.  
  82.   WSTOPPED  = WaitVal{0..6};
  83. #endif
  84.  
  85.  (*  IF state * wStopval = WSTOPPED THEN
  86.   *    stoppedBy := VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wStopsig) DIV 256);
  87.   *    ...
  88.   *  ELSIF state * wTermsig <> WaitVal{} THEN
  89.   *    terminatedBy := VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wTermsig));
  90.   *    coreDumped   := wCoredump IN state;
  91.   *    ...
  92.   *  ELSE
  93.   *    retCode := VAL(INTEGER,CAST(SIGNEDWORD,state * wRetcode) DIV 256);
  94.   *    ...
  95.   *  END;
  96.   *)
  97.  
  98. TYPE
  99. #if reverse_set
  100.   WaitOptions = (
  101.     wait15, wait14, wait13, wait12, wait11, wait10, wait9,
  102.     wait8,  wait7,  wait6,  wait5,  wait4,  wait3,  wait2,
  103.     WUNTRACED, (* 0002H, auch gestoppte Unterprozesse beruecksichtigen *)
  104.     WNOHANG    (* 0001H, nicht auf Beendigung warten, sofort zurueck *)
  105.   );
  106. #else
  107.   WaitOptions = (
  108.     WNOHANG,   (* 0001H, nicht auf Beendigung warten, sofort zurueck *)
  109.     WUNTRACED, (* 0002H, auch gestoppte Unterprozesse beruecksichtigen *)
  110.     wait2, wait3,  wait4,  wait5,  wait6,  wait7,  wait8,
  111.     wait9, wait10, wait11, wait12, wait13, wait14, wait15
  112.   );
  113. #endif
  114.  
  115.   WaitOption = PACKEDSET OF WaitOptions;
  116.  
  117.  
  118. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  119.  
  120.  PROCEDURE getpid ( ): pidT;
  121.  
  122.  PROCEDURE getppid ( ): pidT;
  123.  
  124. (*--------------------------------------------------------------------------
  125.  | Liefert die Kennung des eigenen bzw. des uebergeordneten Prozesses.      |
  126.  |                                                                          |
  127.  | GEMDOS: Aus der Adresse der BasePage wird ein eindeutiger Wert berechnet.|
  128.  |   MiNT: Keine Besonderheiten.                                            |
  129.   --------------------------------------------------------------------------*)
  130.  
  131.  
  132.  PROCEDURE getuid ( ): uidT;
  133.  
  134.  PROCEDURE getgid ( ): gidT;
  135.  
  136.  PROCEDURE geteuid ( ): uidT;
  137.  
  138.  PROCEDURE getegid ( ): gidT;
  139.  
  140.  PROCEDURE setuid ((* EIN/ -- *) uid : uidT ): INTEGER;
  141.  
  142.  PROCEDURE setgid ((* EIN/ -- *) gid : gidT ): INTEGER;
  143.  
  144. (*--------------------------------------------------------------------------
  145.  | Funktionen fuer das Abfragen und Setzen diverser Kennungen:              |
  146.  | "getuid/gid"  : liefern reale Benutzer- bzw. Gruppenkennung des aufrufen-|
  147.  |                 den Prozesses.                                           |
  148.  | "geteuid/gid" : liefern effektive Benutzer- bzw. Gruppenkennung des auf- |
  149.  |                 rufenden Prozesses.                                      |
  150.  | "setuid/gid"  : setzen reale und effektive Benutzer- bzw. Gruppenkennung |
  151.  |                 des aufrufenden Prozesses auf <uid> bzw. <gid>.          |
  152.  |                                                                          |
  153.  | Die realen Kennungen identifizieren den Benutzer bzw. die Gruppe.        |
  154.  |                                                                          |
  155.  | Der Zugriff auf Systemressourcen (z.B. Dateien) wird ueber die effektiven|
  156.  | Kennungen geregelt, die normalerweise gleich den realen Kennungen sind,  |
  157.  | es sei denn, es wird ein Programm ausgefuehrt, das die ``set user id''   |
  158.  | oder ``set group id'' Bits im Modusfeld gesetzt hat, wodurch der ausfueh-|
  159.  | rende Prozess als effektive Kennung die Kennung des Dateibesitzers und   |
  160.  | damit auch seine Zugriffsberechtigung bekommt. Die realen Kennungen      |
  161.  | werden hiedurch aber nicht beeinflusst.                                  |
  162.  |                                                                          |
  163.  | GEMDOS: Die Kennung ist immer gleich Null (``Superuser'').               |
  164.  |   MiNT: Keine Besonderheiten.                                            |
  165.   --------------------------------------------------------------------------*)
  166.  
  167.  
  168.  PROCEDURE getpgrp ( ): pidT;
  169.  
  170.  PROCEDURE setpgid ((* EIN/ -- *) pid  : pidT;
  171.                     (* EIN/ -- *) pgid : pidT ): INTEGER;
  172.  
  173.  PROCEDURE setsid ( ): pidT;
  174.  
  175. (*--------------------------------------------------------------------------
  176.  | "getpgrp()": ermittelt die Prozessgruppe des aufrufenden Prozesses.      |
  177.  | "setpgid()": Setzt die Prozessgruppe des Prozesses <pid> auf den Wert    |
  178.  |              <pgid>. Wenn <pid> oder <pgid> Null sind, wird stattdessen  |
  179.  |              die Prozesskennung des aufrufenden Prozesses eingesetzt.    |
  180.  | "setsid()" : Der aufrufende Prozess verliert sein Kontrollterminal (von  |
  181.  |              dem aus bestimmte Tasten Signale ausloesen koennen - fuer   |
  182.  |              ``job control''), und wird zum einzigen Mitglied einer      |
  183.  |              neuen Prozessgruppe, die das einzige Mitglied einer neuen   |
  184.  |              ``Session'' ist. Die Prozessgruppe ist die Prozesskennung   |
  185.  |              des aufrufenden Prozesses. Wenn der Prozess bereits eine    |
  186.  |              Prozessgruppe anfuehrt (Kennung der Prozesses ist auch Ken- |
  187.  |              nung der Prozessgruppe), darf die Funktion nicht ausgefuehrt|
  188.  |              werden.                                                     |
  189.  |                                                                          |
  190.  | GEMDOS: "getpgrp()" liefert den gleichen Wert wie "getpid()". Fuer <pid> |
  191.  |         und <pgid> bei "setpgid()" sind nur Null und der Wert von        |
  192.  |         "getpid()" erlaubt. "setsid()" liefert immer -1 (errno = 'EPERM')|
  193.  |   MiNT: "getpgrp()" und "setpgid()": Keine Besonderheiten.               |
  194.  |         "setsid()": Der Unterschied zwischen einer ``Session'' und einer |
  195.  |         Prozessgruppe ist mir nicht klar. Ueberhaupt ist mir unklar, in- |
  196.  |         wieweit "MiNT-psetpgrp()" den POSIX-Funktionen "setpgid()" und   |
  197.  |         "setsid()" entspricht, deshalb kann es sein, dass die Funktions- |
  198.  |         weise nicht ganz korrekt ist (Das Kontrollterminal wird jeden-   |
  199.  |         falls nicht ``abgehaengt'').                                     |
  200.   --------------------------------------------------------------------------*)
  201.  
  202.  
  203.  PROCEDURE fork ( ): pidT;
  204.  
  205. (*--------------------------------------------------------------------------
  206.  | Der aktuelle Prozess wird in zwei gleichartige Prozesse aufgeteilt, aber |
  207.  | mit getrenntem Speicherbereich und unterschiedlichen Prozesskennungen.   |
  208.  | Konnte der neue Prozess nicht erzeugt werden, wird dem aufrufenden Pro-  |
  209.  | zess ein Fehler gemeldet; sonst liefert die Funktion dem aufrufenden     |
  210.  | (= Parent) die (positive) Prozesskennung des neuen Prozesses (= Child)   |
  211.  | und dem neuen Prozess eine Null.                                         |
  212.  |                                                                          |
  213.  | GEMDOS: Liefert immer -1 (errno = 'ENOSYS').                             |
  214.  |   MiNT: Keine Besonderheiten.                                            |
  215.   --------------------------------------------------------------------------*)
  216.  
  217.  
  218.  PROCEDURE vfork ( ): pidT;
  219.  
  220. (*--------------------------------------------------------------------------
  221.  | Funktion wie "fork()", die Prozesse benutzen aber denselben Speicher-    |
  222.  | bereich, insbesondere benutzen sie auch denselben Stack.                 |
  223.  |                                                                          |
  224.  | GEMDOS/MiNT: Bei der Anwendung der Funktion ist etwas Vorsicht geboten:  |
  225.  | Zwischen dem "vfork()" und dem Pterm oder "execv*()" des Kindprozesses   |
  226.  | darf der Stackpointer nicht hochgesetzt werden, etwa durch einen Aufruf  |
  227.  | von "vfork()" innerhalb einer WITH- oder FOR-Anweisung oder innerhalb    |
  228.  | einer Prozedur, und dem Aufruf von "execv*()" ausserhalb, denn sonst     |
  229.  | ueberschreibt der Kindprozess fuer den Elternprozess wichtige Informa-   |
  230.  | tionen, wenn er etwas auf dem Stack ablegt; und das geschieht spaetestens|
  231.  | beim Terminieren des Kindprozesses oder dem Ueberlagern mit einem neuen  |
  232.  | Programm durch "execv*()", denn die Parameter werden auf dem Stack abge- |
  233.  | legt. Das Ergebnis ist mit Sicherheit ein Absturz, vor allem, wenn       |
  234.  | "vfork()" innerhalb einer Prozedur aufgerufen wird -- dann fehlt naemlich|
  235.  | die Return-Adresse fuer den Elternprozess. Die Gruende fuer die Schwie-  |
  236.  | rigkeiten sind allerdings bei GEMDOS und MiNT unterschiedlich:           |
  237.  | Unter MiNT wird fuer Eltern- und Kindprozess tatsaechlich derselbe Stack |
  238.  | benutzt, mit den eben erwaehnten Folgen. Unter GEMDOS wird "vfork()"     |
  239.  | durch "tfork()" emuliert, wodurch der Kindprozess einen anderen Stack    |
  240.  | erhaelt, und folglich keine vorher auf dem Stack abgelegte Werte mehr    |
  241.  | gueltig sind.                                                            |
  242.  |                                                                          |
  243.  | Mit Megamax-Modula funktioniert die Funktion aus unerfindlichen Gruenden |
  244.  | weder unter GEMDOS noch unter MiNT.                                      |
  245.   --------------------------------------------------------------------------*)
  246.  
  247.  
  248. (* nicht POSIX *)
  249.  PROCEDURE SetStacksize ((* EIN/ -- *) stacksize : CARDINAL );
  250.  
  251. (* nicht POSIX *)
  252.  PROCEDURE tfork ((* EIN/ -- *) func : ThreadProc;
  253.                   (* EIN/ -- *) arg  : ANYLONG    ): INTEGER;
  254.  
  255. (*--------------------------------------------------------------------------
  256.  | "tfork()" generiert aus einer Funktion vom Typ 'ThreadProc' einen neuen  |
  257.  | Prozess mit eigener Prozesskennung und eigenem Stack, der sonstige       |
  258.  | Adressraum ist aber derselbe wie beim aufrufenden Prozess, d.h. auf      |
  259.  | globale Variablen wird gemeinsam zugegriffen. Deshalb ist auch Vorsicht  |
  260.  | bei der Benutzung von Bibliotheksfunktionen innerhalb des neuen Prozesses|
  261.  | (``Thread'') geboten; insbesondere sollte die Speicherverwaltung nicht   |
  262.  | verwendet werden ("NEW()", "DISPOSE()" ...). Ansonsten muss ausprobiert  |
  263.  | werden, was funktioniert.                                                |
  264.  | Mit "SetStacksize()" laesst sich die Stackgroesse des neuen Prozesses    |
  265.  | festlegen; sie kann aber nicht kleiner als 'MINSTACKSIZE' werden.        |
  266.   --------------------------------------------------------------------------*)
  267.  
  268.  
  269.  PROCEDURE execve ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  270.                    (* EIN/ -- *)     argv : StrArray;
  271.                    (* EIN/ -- *)     envp : StrArray      ): INTEGER;
  272.  
  273.  PROCEDURE execv ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  274.                   (* EIN/ -- *)     argv : StrArray      ): INTEGER;
  275.  
  276.  PROCEDURE execvp ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  277.                    (* EIN/ -- *)     argv : StrArray      ): INTEGER;
  278.  
  279. (*--------------------------------------------------------------------------
  280.  | Ersetzt den aufrufenden Prozess durch einen neuen, der aus dem Programm  |
  281.  | gebildet wird, dessen Dateiname <prg> ist. <args> und <env> sind Felder  |
  282.  | aus Zeigern auf Parameter und Environment-Variablen, sodass der neue     |
  283.  | Prozess diese als Elemente der Kommandozeile bzw. als Environment-Variab-|
  284.  | len holen kann.                                                          |
  285.  | Ist <envp> = NULL, wird das augenblickliche Environment vererbt.         |
  286.  | Falls ein Fehler auftritt, wird ein negativer Wert zurueckgeliefert,     |
  287.  | andernfalls kehrt die Funktion NICHT zum Aufrufer zurueck, da dieser     |
  288.  | durch das neue Programm ersetzt wurde.                                   |
  289.  | Mit der Kombination "fork()"&"execve()" koennen somit neue Prozesse      |
  290.  | gestartet werden.                                                        |
  291.  |                                                                          |
  292.  | Spezielle Versionen von "execve()":                                      |
  293.  |                                                                          |
  294.  | "execv()" : es wird das augenblickliche Environment vererbt.             |
  295.  | "execvp()": das augenblickliche Environment wird vererbt, und <prg> wird |
  296.  |             in allen in PATH angegebenen Verzeichnissen gesucht.         |
  297.  |                                                                          |
  298.  | GEMDOS: Funktioniert, ist aber ohne "fork()" nicht sinnvoll.             |
  299.  |   MiNT: Keine Besonderheiten.                                            |
  300.  | Die Kommandozeilenparameter werden dem neuen Programm ueber die normale  |
  301.  | Kommandozeile in der BasePage und das ARGV-Verfahren (einschlisslich     |
  302.  | Erweiterung fuer leere Argumente) mitgeteilt.                            |
  303.   --------------------------------------------------------------------------*)
  304.  
  305.  
  306.  
  307.  
  308.  PROCEDURE waitpid ((* EIN/ -- *)     pid     : pidT;
  309.                     (* -- /AUS *) VAR state   : WaitVal;
  310.                     (* EIN/ -- *)     options : WaitOption ): pidT;
  311.  
  312. (*--------------------------------------------------------------------------
  313.  | Wartet auf die Beendigung oder das Stoppen eines vom aufrufenden Prozess |
  314.  | gestarteten Unterprozesses. Als Funktionswert wird die 'pid' des ent-    |
  315.  | sprechenden Prozesses oder -1 bei einem Fehler (z.B. wenn keine Prozesse |
  316.  | gestartet wurden) zurueckgeliefert. In <state> steht kodiert die Ursache |
  317.  | der Beendigung oder des Stoppens (siehe Definition von 'WaitVal').       |
  318.  | Mit <options> wird das Verhalten der Prozedur festgelegt (siehe Def. von |
  319.  | 'WaitOptions').                                                          |
  320.  | Mit <pid> wird festgelegt, welche Unterprozesse beruecksichtigt werden   |
  321.  | sollen:                                                                  |
  322.  |                                                                          |
  323.  |   <pid> = -1: alle Unterprozesse                                         |
  324.  |   <pid> >  0: nur Unterprozess mit dieser Prozesskennung                 |
  325.  |   <pid> =  0: alle Unterprozesse mit der gleichen Prozessgruppenkennung  |
  326.  |               wie der aufrufende Prozess                                 |
  327.  |   <pid> < -1: alle Unterprozesse, die |<pid>| als Prozessgruppenkennung  |
  328.  |               haben                                                      |
  329.  |                                                                          |
  330.  | GEMDOS: Wenn <pid> = 0 oder -1, wird die Prozesskennung des letzten mit  |
  331.  |         "tfork()" gestarteten Unterprozesses geliefert, sonst wird immer |
  332.  |         -1 geliefert (errno = 'ECHILD').                                 |
  333.  |   MiNT: Keine Besonderheiten.                                            |
  334.   --------------------------------------------------------------------------*)
  335.  
  336.  PROCEDURE wait ((* -- /AUS *) VAR state : WaitVal ): pidT;
  337.  
  338. (*--------------------------------------------------------------------------
  339.  | Aequivalent zu "waitpid(-1, state, WaitOption{})", es werden also keine  |
  340.  | gestoppten Unterprozesse beruecksichtigt.                                |
  341.  |                                                                          |
  342.  | GEMDOS: siehe "waitpid()".                                               |
  343.  |   MiNT: Keine Besonderheiten.                                            |
  344.   --------------------------------------------------------------------------*)
  345.  
  346.  
  347.  PROCEDURE WIFEXITED   ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  348.  PROCEDURE WEXITSTATUS ((* EIN/ -- *) state : WaitVal ): INTEGER;
  349.  
  350.  PROCEDURE WIFSIGNALED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  351.  PROCEDURE WTERMSIG    ((* EIN/ -- *) state : WaitVal ): CARDINAL;
  352.  
  353.  PROCEDURE WIFSTOPPED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  354.  PROCEDURE WSTOPSIG   ((* EIN/ -- *) state : WaitVal ): CARDINAL;
  355.  
  356. (*--------------------------------------------------------------------------
  357.  | Diese Funktionen sind bei POSIX als Makros definiert.                    |
  358.  |                                                                          |
  359.  | "WIFEXITED()"  : TRUE, genau dann, wenn der Unterprozess ``normal'' been-|
  360.  |                  det wurde, d.h. nicht durch ein Signal.                 |
  361.  | "WEXITSTATUS()": Falls "WIFEXITED()" = TRUE, wird der Returncode des     |
  362.  |                  Unterprozesses geliefert. Dabei werden aber nur die     |
  363.  |                  unteren 8 Bit des Returncodes benutzt und vorzeichen-   |
  364.  |                  richtig erweitert.                                      |
  365.  |                  Wenn "WIFEXITED()" = FALSE, ist der Funktionswert nicht |
  366.  |                  definiert !                                             |
  367.  | "WIFSIGNALED()": TRUE, genau dann, wenn der Unterprozess durch ein Signal|
  368.  |                  beendet wurde.                                          |
  369.  | "WTERMSIG()"   : Falls "WIFSIGNALED()" = TRUE, wird der Ordinalwert des  |
  370.  |                  beendenden Signals geliefert.                           |
  371.  |                  Wenn "WIFSIGNALED()" = FALSE,ist der Funktionswert nicht|
  372.  |                  definiert !                                             |
  373.  | "WIFSTOPPED()" : TRUE, genau dann, wenn der Unterprozess momentan ge-    |
  374.  |                  stoppt, aber nicht beendet ist (``Job Control'').       |
  375.  | "WSTOPSIG()"   : Falls "WIFSTOPPED()" = TRUE, wird der Ordinalwert des   |
  376.  |                  Signals, das den Prozess gestoppt hat, geliefert.       |
  377.  |                  Wenn "WIFSTOPPED()" = FALSE, ist der Funktionswert nicht|
  378.  |                  definiert !                                             |
  379.  |                                                                          |
  380.  | Es sollten ausschliesslich diese Funktionen benutzt werden, um einen     |
  381.  | Status vom Typ 'WaitVal' zu analysieren.                                 |
  382.  |                                                                          |
  383.  | GEMDOS: keine Besonderheiten.                                            |
  384.  |   MiNT: -""-                                                             |
  385.   --------------------------------------------------------------------------*)
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  PROCEDURE times ((* -- /AUS *) VAR buf : TmsRec ): clockT;
  392.  
  393. (*--------------------------------------------------------------------------
  394.  | Liefert Informationen ueber die vom Prozess und seine Unterprozesse ver- |
  395.  | brauchte Zeit (siehe Def. von 'TmsRec'); die Zeiten sind in der Einheit  |
  396.  | 'sys.ClkTck's / Sekunde angegeben.                                       |
  397.  | Als Funktionswert wird die vergangene Zeit seit einem beliebigen, aber   |
  398.  | festen Zeitpunkt in der Vergangenheit zurueckgeliefert; durch mehrmaligen|
  399.  | Aufruf der Funktion koennen so Zeitdifferenzen gemessen werden. Auch hier|
  400.  | ist die Einheit 'sys.ClkTck's / Sekunde.                                 |
  401.  |                                                                          |
  402.  | GEMDOS: Die im System verbrachte Zeit kann nicht festgestellt werden.    |
  403.  |   MiNT: Keine Besonderheiten.                                            |
  404.   --------------------------------------------------------------------------*)
  405.  
  406.  
  407.  
  408.  PROCEDURE Exit ((* EIN/ -- *) retval : INTEGER );
  409.  
  410. (*--------------------------------------------------------------------------
  411.  | Der aufrufende Prozess wird mit dem Returncode <retval> beendet.         |
  412.  | <retVal> sollte im Bereich [-128..127] liegen, da im Typ 'WaitVal' nur   |
  413.  | 8 Bit des Returncodes untergebracht werden koennen.                      |
  414.  | Die Prozedur muesste eigentlich "_exit()" heissen!                       |
  415.  |                                                                          |
  416.  | GEMDOS: keine Besonderheiten.                                            |
  417.  |   MiNT: -""-                                                             |
  418.   --------------------------------------------------------------------------*)
  419.  
  420.  
  421.  
  422.  
  423. (*===========================================================================*)
  424. (* Die folgenden Funktionen haben NICHTS mit POSIX oder *IX zu tun, sind     *)
  425. (* jedoch fuer "PCDOS" und "GEMDOS" notwendig, um ein *IX-like               *)
  426. (* Programmstarten zu ermoeglichen. Fuer *IX sind die Funktionen immerhin    *)
  427. (* bequem.                                                                   *)
  428. (*===========================================================================*)
  429.  
  430. TYPE
  431.   SpawnMode = (
  432.     pOVERLAY, (* Aufrufer wird durch neuen Prozess ersetzt (= exec)*)
  433.     pNOWAIT,  (* neuer Prozess laeuft parallel zum erzeugenden Prozess *)
  434.     pWAIT     (* Erzeugender Prozess wird unterbrochen *)
  435.   );
  436.  
  437. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  438.  
  439.  PROCEDURE spawnve ((* EIN/ -- *)     mode : SpawnMode;
  440.                     (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  441.                     (* EIN/ -- *)     argv : StrArray;
  442.                     (* EIN/ -- *)     envp : StrArray      ): INTEGER;
  443.  
  444. (*--------------------------------------------------------------------------
  445.  | Diese Prozedur fasst die Prozeduren "fork()", "execve()" und "waitpid()" |
  446.  | auf unterschiedliche Weise zusammen.                                     |
  447.  |                                                                          |
  448.  | <mode> = pOVERLAY: "spawnve()" entspricht "execve()"                     |
  449.  | <mode> = pNOWAIT : es wird ein "fork()" ausgefuehrt, und dann <prg> mit  |
  450.  |                    "execve()" gestartet.                                 |
  451.  |                    Rueckgabewert ist entweder -1 und 'errno' wird gesetzt|
  452.  |                    falls beim Aufruf von "spawnve()" etwas schiefgeht,   |
  453.  |                    oder die positive 'pid' des erzeugten Prozesses.      |
  454.  | <mode> = pWAIT   : wie pNOWAIT, aber es wird mit "waitpid()" auf das Ende|
  455.  |                    des erzeugten Prozesses gewartet. Falls beim Aufruf   |
  456.  |                    von "spawnve()" etwas schiefgeht, ist der Rueckgabe-  |
  457.  |                    wert gleich -1 und 'errno' wird gesetzt, ansonsten    |
  458.  |                    wird 'errno' auf Null gesetzt(!), und die unteren 16  |
  459.  |                    Bit des Funktionswertes sind vom Typ 'WaitVal'. Da im |
  460.  |                    oberen Byte von 'WaitVal' der Returncode des aufgeru- |
  461.  |                    fenen Prozesses enthalten ist (falls der Prozess nicht|
  462.  |                    durch ein Signal gestoppt oder terminiert wurde) und  |
  463.  |                    dieser auch negativ sein kann, und 'WaitVal' fuer den |
  464.  |                    Funktionswert auch vorzeichenrichtig auf INTEGER-     |
  465.  |                    Groesse erweitert wird,muss ein Fehler von "spawnve()"|
  466.  |                    durch Inspizieren von 'errno' ermittelt werden:       |
  467.  |                                                                          |
  468.  |                      ret := spawnve(pWAIT,...);                          |
  469.  |                      IF errno <> 0 THEN                                  |
  470.  |                        (* "spawnve()"-Fehler *)                          |
  471.  |                      ...                                                 |
  472.  |                                                                          |
  473.  | GEMDOS/MiNT:                                                             |
  474.  |           Diese Prozedur laeuft fuer <mode> = 'pWAIT' oder 'pOVERLAY'    |
  475.  |           auch ohne MiNT.                                                |
  476.  |           ACHTUNG: Es wird wirklich nur das Programm ueber 'Pexec' ge-   |
  477.  |           startet, es wird weder der Bildschirm geloescht, die Maus aus- |
  478.  |           geschaltet, noch der Critical-Error-Handler umgesetzt! Ehe man |
  479.  |           jetzt aber selbst daran geht dies zu tun, sollte man daran den-|
  480.  |           ken, dass es zum Chaos fuehrt, falls Prozesse parallel laufen  |
  481.  |           (unter MiNT), da es nur einen Bildschirm, eine Maus und einen  |
  482.  |           Error-Handler (vor MiNT 0.95) gibt! Das Problem laesst sich nur|
  483.  |           loesen, wenn TOS-Programme ihre Ausgaben in GEM-Fenster schrei-|
  484.  |           ben, wie dies unter MultiTOS der Fall sein wird.               |
  485.  |           Wenn ein (Unter)Prozess keine Bidschirmausgaben macht, ist dies|
  486.  |           natuerlich kein Problem.                                       |
  487.  |           Ohne MiNT wird Pexec mit Modus 0 (pWAIT) gestartet, sonst      |
  488.  |           sind auch Modus 100 (pNOWAIT) und 200 (pOVERLAY) moeglich.     |
  489.  |           ("MiNT"-Unterstuetzung.)                                       |
  490.   --------------------------------------------------------------------------*)
  491.  
  492.  
  493.  
  494.  PROCEDURE spawnv ((* EIN/ -- *)     mode : SpawnMode;
  495.                    (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  496.                    (* EIN/ -- *)     argv : StrArray      ): INTEGER;
  497.  
  498.  PROCEDURE spawnvp ((* EIN/ -- *)     mode : SpawnMode;
  499.                     (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  500.                     (* EIN/ -- *)     argv : StrArray      ): INTEGER;
  501.  
  502. (*--------------------------------------------------------------------------
  503.  | Spezielle Versionen von "spawnve()":                                     |
  504.  |                                                                          |
  505.  | "spawnv()"  : es wird das augenblickliche Environment vererbt.           |
  506.  | "spawnvp()" : das augenblickliche Environment wird vererbt, und <prg>    |
  507.  |               wird in allen in PATH angegebenen Verzeichnissen gesucht.  |
  508.   --------------------------------------------------------------------------*)
  509.  
  510. END proc.
  511.